import common from "shared/component/common/common";
import { ContainerService } from "shared/component/container/ContainerService";
import Log4R from "shared/component/log/Log4R";
import Vector3TweenStep from "shared/component/tween/Vector3TweenStep";
const loginfo = Log4R.getLog('info');
export class Camera2DServiceImpl extends ContainerService<Ctn.Camera2DService, Ctn.Camera2DEntity> implements Ctn.Camera2DService {
    protected serverCalls: (keyof this)[] = [];
    protected serviceName: keyof Ctn.Services = "camera2DService";

    /** 当前绑定模型 */
    private currentModel?: Model
    /** 屏幕分辨率 */
    private screenSize?: Vector2;

    /** 绑定玩家角色 */
    public bindPlayerCharacter(character: Ctn.character.HumanModel) {
        if (game.Workspace.CurrentCamera) {
            game.Workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable;
        }
        if (common.isLocalPlayerCharacter(character) && this.currentModel !== character) {
            this.bindCharacter(character)
        }
    }
    /** 绑定的物体 */
    rootPart?: Part
    /** 摄像机基础偏移 */
    private offsetVectorObjet?: Vector3Value

    /** 摄像机基础角度 */
    private angleVectorObjet?: Vector3Value
    /** 摄像机基础角度 */
    private cameraFieldOfView?: NumberValue
    /** 摄像机修正偏移 */
    private offsetModify?: Vector3
    private vectortween = new Vector3TweenStep({
        x: false, y: true, z: false
    })
    private cameLockTargetVector = new Instance('Vector3Value');
    /** 摄像机震动偏移 */
    cameraOffsetInstanceShake = new Instance('Vector3Value')
    private step(d: number, camera: Camera) {

        if (!this.rootPart)
            this.rootPart = this.currentModel?.FindFirstChild('HumanoidRootPart') as Part
        if (!this.rootPart) return
        if (!this.offsetVectorObjet) return
        if (!this.angleVectorObjet) return
        const rootPosition = new Vector3(this.rootPart.CFrame.Position.X, this.rootPart.CFrame.Position.Y, this.cameLockTargetVector.Value.Z)
        // const rootPosition = this.rootPart.CFrame.Position;
        const startCFrame = new CFrame(rootPosition).mul(CFrame.Angles(0, math.rad(this.angleVectorObjet.Value.X), 0));
        const targetCframeValue = startCFrame.ToWorldSpace(new CFrame(
            this.offsetVectorObjet.Value
        ));
        const pos = this.vectortween.tweenStepVector3Play(d, targetCframeValue.Position,
            () => {

            }
        );
        // const cameraFocus = startCFrame.ToWorldSpace(new CFrame(0, 0, -10000))
        const cameraCFrame = new CFrame(pos, new Vector3(this.rootPart.Position.X, pos.Y, this.cameLockTargetVector.Value.Z));
        camera.CFrame = cameraCFrame.add(this.cameraOffsetInstanceShake.Value)
            .mul(CFrame.Angles(math.rad(this.angleVectorObjet.Value.Y), 0, 0))//new CFrame(targetCframe.Position).mul(CFrame.fromOrientation(x, y, z));
        camera.Focus = camera.CFrame// new CFrame(this.startCFrame.Position.add(this.GViewVector), this.startCFrame.Position)
    }
    public init(): void {
        loginfo?.info('<-------------Camera2DServiceImpl init-------------->');
        let startmask = common.waitForChild(this.getPlayerGui(), 'startMask', 'ScreenGui')
        //  this.getPlayerGui().FindFirstChild('startMask');
        // if (!startmask?.IsA('ScreenGui')) {
        //     print('wait for startMask')
        //     const x = this.getPlayerGui().ChildAdded.Connect(c => {
        //         if (c.Name === 'startMask') {
        //             startmask = c;
        //         }
        //     })
        // }
        // if (!startmask?.IsA('ScreenGui')) {
        //     throw ("not find startmask")
        // }
        this.screenSize = startmask.AbsoluteSize
        loginfo?.info('this.screenSize', this.screenSize)
        this.cameLockTargetVector.Value = new Vector3(0, 0, 0);
        if (this.screenSize.Y >= 600) {
            this.offsetVectorObjet = this.getConfig('offset', 'Vector3Value');
        } else {
            this.offsetVectorObjet = this.getConfig('offset600', 'Vector3Value');
        }

        this.angleVectorObjet = this.getConfig('angle', 'Vector3Value');
        const callBackOfCameraFieldOfView = () => {
            const camera = game.Workspace.CurrentCamera
            if (camera) {
                if (this.cameraFieldOfView?.Value)
                    camera.FieldOfView = this.cameraFieldOfView.Value
            }
        }
        this.cameraFieldOfView = this.getConfig('cameraFieldOfView', 'NumberValue', callBackOfCameraFieldOfView);
        callBackOfCameraFieldOfView()

    }
    /** 绑定摄像机到模型 */
    private bindCharacter(character: Ctn.character.HumanModel) {
        this.currentModel = character;

        const RunService = game.GetService('RunService');
        pcall(() => {
            RunService.UnbindFromRenderStep('cameraRender')

        });
        const camera = game.Workspace.CurrentCamera
        if (camera) {

            RunService.BindToRenderStep('cameraRender', Enum.RenderPriority.Camera.Value, (d) => {
                try {
                    if (camera)
                        this.step(d, camera)
                } catch (e) {

                }
            })
        }
    }
}